#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <pthread.h> // 原生线程库的头文件

const int threadnum = 5;

// 传递字符串
// void *handlerTask(void *args)
// {
//   // std::string threadname =static_cast<char*>(args);
//   const char *threadname = static_cast<char *>(args);
//   while (true)
//   {
//     std::cout << "I am " << threadname << std::endl;
//     sleep(2);
//   }

//   delete[] threadname;

//   return nullptr;
// }

// int main()
// {
//   std::vector<pthread_t> threads;
//   for (int i = 0; i < threadnum; i++)
//   {
//     char *threadname = new char[64];
//     snprintf(threadname, 64, "Thread-%d", i + 1);

//     pthread_t tid;
//     pthread_create(&tid, nullptr, handlerTask, threadname);
//     threads.push_back(tid);
//   }
//   for (auto &tid : threads)
//   {
//     pthread_join(tid, nullptr);
//   }
// }

// 传递对象
// 任务类，完成两数相加的任务
class Task
{
public:
  Task()
  {
  }
  void SetData(int x, int y)
  {
    datax = x;
    datay = y;
  }
  int Excute()
  {
    return datax + datay;
  }
  ~Task()
  {
  }

private:
  int datax;
  int datay;
};

// 线程类
class ThreadData : public Task
{
public:
  ThreadData(int x, int y, const std::string &threadname) : _threadname(threadname)
  {
    _t.SetData(x, y);
  }
  std::string threadname()
  {
    return _threadname;
  }
  int run()
  {
    return _t.Excute();
  }

private:
  std::string _threadname; // 线程名
  Task _t;                 // 任务
};

// 任务结果类
class Result
{
public:
  Result() {}
  ~Result() {}
  void SetResult(int result, const std::string &threadname)
  {
    _result = result;
    _threadname = threadname;
  }
  void Print()
  {
    std::cout << _threadname << " : " << _result << std::endl;
  }

private:
  int _result;             // 相加结果
  std::string _threadname; // 线程名
};

// 线程函数
void *handlerTask(void *args)
{
  ThreadData *td = static_cast<ThreadData *>(args);

  std::string name = td->threadname();

  Result *res = new Result();
  int result = td->run();

  res->SetResult(result, name);

  // std::cout << name << "run result : " << result << std::endl;
  delete td;

  sleep(2);
  return res;
}

int main()
{
  std::vector<pthread_t> threads;
  for (int i = 0; i < threadnum; i++)
  {
    char threadname[64];
    snprintf(threadname, 64, "Thread-%d", i + 1);
    ThreadData *td = new ThreadData(10, 20, threadname);

    pthread_t tid;
    pthread_create(&tid, nullptr, handlerTask, td);
    threads.push_back(tid);
  }
  std::vector<Result *> result_set;
  void *ret = nullptr;
  for (auto &tid : threads)
  {
    pthread_join(tid, &ret);
    result_set.push_back((Result *)ret);
  }

  for (auto &res : result_set)
  {
    res->Print();
    delete res;
  }
}